package com.jieli.bt.att.ui.device.details

import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.os.Looper
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.jieli.bt.att.data.constant.Config
import com.jieli.bt.att.tool.ble.interfaces.BleEventCallback
import com.jieli.bt.att.ui.common.BluetoothViewModel
import com.jieli.bt.att.util.BluetoothUtil
import com.jieli.bt.att.util.CHexConver
import com.jieli.bt.att.util.UuidUtil
import com.jieli.logcat.JL_Log
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.UUID

/**
 * DeviceDetailsViewModel
 * @author zqjasonZhong
 * @since 2025/3/28
 * @email zhongzhuocheng@zh-jieli.com
 * @desc 设备详情界面实现逻辑
 */
class DeviceDetailsViewModel(val device: BluetoothDevice) : BluetoothViewModel() {

    companion object {
        private val dataFormat = SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS", Locale.ENGLISH)
    }

    val logMLD = MutableLiveData<String>()

    private val btCallback = object : BleEventCallback() {

        override fun onBleDataNotification(
            device: BluetoothDevice?,
            serviceUuid: UUID?,
            characteristicsUuid: UUID?,
            data: ByteArray?
        ) {
            if (!BluetoothUtil.deviceEquals(device, this@DeviceDetailsViewModel.device)) return
            logMsg(
                "[Received Data] : (${UuidUtil.read16BitUUID(serviceUuid!!)}) " +
                        ": (${UuidUtil.read16BitUUID(characteristicsUuid!!)}) <--- \n${
                            CHexConver.byte2HexStr(
                                data
                            )
                        }"
            )
        }

    }

    init {
        bleManager.registerBleEventCallback(btCallback)
    }

    override fun onCleared() {
        bleManager.unregisterBleEventCallback(btCallback)
        super.onCleared()
    }

    fun printDeviceInfo() {
        if (bleManager.isConnectedDevice(device)) {
            bleManager.getConnectedBtGatt(device)?.let { gatt ->
                logMsg(
                    BluetoothUtil.printBleGattServices(
                        getContext(),
                        device,
                        gatt,
                        BluetoothGatt.GATT_SUCCESS
                    )
                )
            }
        }
    }

    fun sendData(data: ByteArray) {
        bleManager.writeDataByBleAsync(
            device, Config.BLE_SERVICE_UUID, Config.BLE_WRITE_UUID, data
        ) { _, serviceUUID, characteristicUUID, result, value ->
            logMsg(
                "[Send data] : (${UuidUtil.read16BitUUID(serviceUUID)}) " +
                        ": (${UuidUtil.read16BitUUID(characteristicUUID)}) | $result --->  \n${
                            CHexConver.byte2HexStr(
                                value
                            )
                        }"
            )
        }
    }

    private fun logMsg(content: String) {
        JL_Log.d(tag, "logMsg", content)
        val msg = BluetoothUtil.formatString(
            "%s  %s",
            dataFormat.format(Calendar.getInstance().time),
            content
        )
        if (Thread.currentThread().id == Looper.getMainLooper().thread.id) {
            logMLD.value = msg
        } else {
            logMLD.postValue(msg)
        }
    }

    @Suppress("UNCHECKED_CAST")
    class Factory(private val device: BluetoothDevice) : ViewModelProvider.Factory {

        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return DeviceDetailsViewModel(device) as T
        }
    }
}